package com.jyy.prefabricated.service.impl;


import cn.hutool.core.io.FileUtil;
import com.alibaba.fastjson.JSON;
import com.jyy.prefabricated.dto.TrainingOrganizationExamDto;
import com.jyy.prefabricated.entity.*;
import com.jyy.prefabricated.enums.ExtractingStatusEnum;
import com.jyy.prefabricated.enums.QuestionTypeEnum;
import com.jyy.prefabricated.mapper.*;
import com.jyy.prefabricated.service.BosService;
import com.jyy.prefabricated.service.DowloadService;
import com.jyy.prefabricated.service.StudentExamQuestionService;
import com.jyy.prefabricated.service.StudentExerciseQuestionService;
import com.jyy.prefabricated.utils.ConvertByPoi;
import com.jyy.prefabricated.utils.Html2Word;
import com.jyy.prefabricated.utils.HtmlText;
import com.jyy.prefabricated.utils.ImageProcessUtil;
import com.jyy.prefabricated.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;


@Slf4j
@Service
public class DowloadServiceImpl implements DowloadService {

    @Resource
    private QuestionMapper questionMapper;

    @Resource
    private OptionMapper optionMapper;

    @Resource
    private BosService bosService;

    @Resource
    private StudentExamQuestionService studentExamQuestionService;

    @Autowired
    private StudentExerciseQuestionService studentExerciseQuestionService;

    @Resource
    private ExamPaperMapper paperMapper;

    @Resource
    private StudentExamMapper studentExamMapper;

    @Resource
    private ExamMapper examMapper;

    //    public static final String ww = "src\\main\\resources\\templates\\ww.doc";
//    public static final String word = "src\\main\\resources\\templates\\word\\";
    @Value("${file.path.ww}")
    private String ww;
    @Value("${file.path.word}")
    private String word;

    @Override
    public String dowloadPaper(Integer id, Integer paperType) {
        String resultURl = "";
        String html = "";
        //空白试卷
        if (paperType == 0) {
            html = createContextBlank(id);
        } else {
            html = createContextFull(id);
        }
        InputStream inputStream = null;
        OutputStream outputStream = null;
        File file = new File(ww);
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        try {
            String context = HtmlText.WORD_HEAD + ImageProcessUtil.processImage(html) + HtmlText.WORD_FOOT;
            byte[] b = context.getBytes(StandardCharsets.UTF_8);
            //将字节数组包装到流中
            inputStream = new ByteArrayInputStream(b);

            long l = System.currentTimeMillis();

            outputStream = Files.newOutputStream(Paths.get(ww));
            Html2Word poiConvert = new ConvertByPoi(inputStream, outputStream);
            poiConvert.convert();
            log.info("poi方式导出用时:{}ms", System.currentTimeMillis() - l);

            String random = UUID.randomUUID().toString().replace("-", "");
            ExamPaper examPaper = paperMapper.selectByPrimaryKey(id);
            if (paperType == 0) {
                String objectName = examPaper.getName() + "(空白试卷)" + random + ".doc";
                resultURl = bosService.putFile(file, objectName);
            } else {
                String objectName = examPaper.getName() + "(完整试卷)" + random + ".doc";
                resultURl = bosService.putFile(file, objectName);
            }
            IOUtils.closeQuietly(inputStream);
            IOUtils.closeQuietly(outputStream);

        } catch (IOException e) {
            e.printStackTrace();
        }
        return resultURl;
    }

    /*生成下载空白试卷所需要的html*/
    public String createContextBlank(Integer id) {
        String resultURl = "";
        ExamPaper examPaper = paperMapper.selectByPrimaryKey(id);
        if (examPaper == null) {
            return resultURl;
        }
        List<Question> questionList = new ArrayList<>();
        if (examPaper.getAreas().size() > 0) {
            for (ExamPaperArea examPaperArea : examPaper.getAreas()) {
                if (examPaperArea.getRules().size() > 0) {
                    //随机出题
                    if (ExtractingStatusEnum.RANDOM.getValue().equals(examPaperArea.getExtractingStatus())) {
                        for (ExamPaperAreaRule examPaperAreaRule : examPaperArea.getRules()) {
                            List<Question> alllist = questionMapper.selectByParams(examPaperAreaRule.getQuestionBankId(), examPaperAreaRule.getQuestionType(), examPaperAreaRule.getStemType(), null, null, examPaperAreaRule.getDifficulty(), null, null, null);
                            Collections.shuffle(alllist);
                            //选取随机的集合元素
                            List<Question> randomSeries = alllist.subList(0, examPaperAreaRule.getQuestionCount());
                            for (int i = 0; i < examPaperAreaRule.getQuestionCount(); i++) {
                                randomSeries.get(i).setGrade(examPaperAreaRule.getGrade());
                            }
                            questionList.addAll(randomSeries);
                        }
                    } else if (ExtractingStatusEnum.ORDER.getValue().equals(examPaperArea.getExtractingStatus())) {
                        //顺序出题
                        for (ExamPaperAreaRule examPaperAreaRule : examPaperArea.getRules()) {
                            List<Question> alllist = questionMapper.selectByParams(examPaperAreaRule.getQuestionBankId(), examPaperAreaRule.getQuestionType(), examPaperAreaRule.getStemType(), null, null, examPaperAreaRule.getDifficulty(), null, null, null);
                            List<Question> randomSeries = alllist.subList(0, examPaperAreaRule.getQuestionCount());
                            for (int i = 0; i < examPaperAreaRule.getQuestionCount(); i++) {
                                randomSeries.get(i).setGrade(examPaperAreaRule.getGrade());
                            }
                            questionList.addAll(randomSeries);
                        }
                    } else if (ExtractingStatusEnum.AUTONOMY.getValue().equals(examPaperArea.getExtractingStatus())) {
                        questionList.addAll(questionMapper.selectByAreaId(examPaperArea.getId()));
                    }

                }

            }
        }
        StringBuffer htmlStr = new StringBuffer();
        htmlStr.append("  <meta charset=\"UTF-8\" /> \n" +
                "  <title>Title</title> \n" +
                "  <style>    * {      margin: 0;      padding: 0;      font-size: 16px;      color: #323232;      font-weight: bold;    }    html,    body {      /*height: 100%;*/    }    .contianer {      width: 500px;      padding: 15px 0 0 15px;      box-sizing: border-box;    }    .flex {      display: flex;    }    .layout_column {      display: flex;      flex-direction: column;    }    .layout_bottom {      display: flex;      align-items: flex-end;    }    .layout_center {      display: flex;      align-items: center;    }    h3 {      text-align: center;    }    .option-box {      padding: 10px 0 0 20px;      box-sizing: border-box;    }    .underline {      width: 80px;      border-bottom: 1px #323232 solid;    }  </style>\n" +
                " </head>\n" +
                "\n" +
                "<body>" +
                "\n");

        htmlStr.append("  <div class=\"contianer\">\n" +
                "    <h3>" + examPaper.getName() + "</h3>\n" +

                "    <div class=\"layout_bottom\">\n" +
                "      <span>姓名:</span>\n" +
                "      <div class=\"underline\"></div>\n" +
                "    </div>\n" +

                "    <div class=\"flex\">\n" +
                "      <span>注意事项:</span>\n" +
                "      <div class=\"layout_column\">\n" +
                "        <span>1.答题前填写好自己的姓名等信息</span>\n" +
                "<br />" +
                "        <span>2.请将答案正确填写在答题卡上</span>\n" +
                "      </div>\n" +
                "    </div>\n" +
                "    </div>\n" +
                "<br />"
        );
        int count = 0;
        for (Question question : questionList) {
            count++;
            //单选题、多选题
            if (question.getQuestionType().equals(QuestionTypeEnum.SINGLE.getValue()) || question.getQuestionType().equals(QuestionTypeEnum.MULTIPLE.getValue())) {
                List<Option> optionList = optionMapper.selectByQuestionId(question.getId());
                htmlStr.append("<div>");
                if (question.getQuestionType().equals(QuestionTypeEnum.SINGLE.getValue())) {
                    htmlStr.append("<div>" + count + ".(单选题 " + question.getGrade() + "分)" + question.getName() + "</div>");
                } else {
                    htmlStr.append("<div>" + count + ".(多选题 " + question.getGrade() + "分)" + question.getName() + "</div>");
                }
                char emumOption = 'A';
                for (Option option : optionList) {
                    htmlStr.append(" <div class=\"option-box layout_column\"><span>" + emumOption + "." + option.getContent() + "</span></div>");
                    emumOption = (char) (emumOption + 1);
                }
                htmlStr.append("</div>");
                htmlStr.append("<br />");
            }
            //判断题
            else if (question.getQuestionType().equals(QuestionTypeEnum.JUDGE.getValue())) {
                htmlStr.append("<div>");
                htmlStr.append("<div>" + count + ".(判断题 " + question.getGrade() + "分)" + question.getName() + "</div>" +
                        "<div class=\"option-box layout_column\">\n" +
                        "        <span>A.对</span>\n" +
                        "        <span>B.错</span>\n" +
                        "      </div>");
                htmlStr.append("</div>");
                htmlStr.append("<br />");

            }
            //填空题
            else if (question.getQuestionType().equals(QuestionTypeEnum.GAP.getValue())) {
                htmlStr.append("<div>");
                htmlStr.append("<div>" + count + ".(填空题 " + question.getGrade() + "分)" + question.getName() + "</div>");
                htmlStr.append("</div>");
                htmlStr.append("<br />");

            }

            //问答题
            else if (question.getQuestionType().equals(QuestionTypeEnum.ESSAY.getValue())) {
                htmlStr.append("<div>");
                htmlStr.append("<div>" + count + ".(问答题 " + question.getGrade() + "分)" + question.getName() + "</div>");
                htmlStr.append("</div>");
                htmlStr.append("<br />");

            }
            //材料题
            else if (question.getQuestionType().equals(QuestionTypeEnum.MATERIALS.getValue())) {
                //材料题题目内容
                htmlStr.append("<div class=\"paddingTop\"><span><p>" + count + ".(材料题 " + question.getGrade() + "分)" + question.getName() + "</p></span></div>");

                //材料题子题目（判断、单选、多选、问答、填空）
                List<Question> list = questionMapper.selectByParams(null, null, null, null, null, null, question.getId(), null, null);

                int p = 0;
                for (Question materialQuestion : list) {
                    p++;
                    //单选题、多选题
                    if (materialQuestion.getQuestionType().equals(QuestionTypeEnum.SINGLE.getValue()) || materialQuestion.getQuestionType().equals(QuestionTypeEnum.MULTIPLE.getValue())) {
                        htmlStr.append("<div>");

                        if (materialQuestion.getQuestionType().equals(QuestionTypeEnum.SINGLE.getValue())) {

                            htmlStr.append("<div >" + p + ".(单选题 " + materialQuestion.getGrade() + "分)" + materialQuestion.getName() + "</div>");
                        } else {
                            htmlStr.append("<div >" + p + ".(多选题 " + materialQuestion.getGrade() + "分)" + materialQuestion.getName() + "</div>");
                        }
                        //题目选项集合
                        List<Option> optionList = optionMapper.selectByQuestionId(materialQuestion.getId());

                        char emumOption = 'A';
                        for (Option option : optionList) {
                            htmlStr.append(" <div class=\"option-box layout_column\"><span>" + emumOption + "." + option.getContent() + "</span></div>");
                            emumOption = (char) (emumOption + 1);
                        }
                        htmlStr.append("</div>\n");
                        htmlStr.append("<br />");

                    } else if (materialQuestion.getQuestionType().equals(QuestionTypeEnum.JUDGE.getValue())) {

                        htmlStr.append("<div>" + p + ".(判断题 " + materialQuestion.getGrade() + "分)" + materialQuestion.getName() + "</div>" +
                                "<div class=\"option-box layout_column\">\n" +
                                "        <span>A.对</span>\n" +
                                "        <span>B.错</span>\n" +
                                "      </div>");
                        htmlStr.append("</div>");
                        htmlStr.append("<br />");
                    }
                    //填空题
                    else if (materialQuestion.getQuestionType().equals(QuestionTypeEnum.GAP.getValue())) {
                        htmlStr.append("<div>");
                        htmlStr.append("<div>" + p + ".(填空题 " + materialQuestion.getGrade() + "分)" + materialQuestion.getName() + "</div>");
                        htmlStr.append("</div>");
                        htmlStr.append("<br />");
                    }
                    //问答题
                    else if (materialQuestion.getQuestionType().equals(QuestionTypeEnum.ESSAY.getValue())) {
                        htmlStr.append("<div>");
                        htmlStr.append("<div>" + p + ".(问答题 " + materialQuestion.getGrade() + "分)" + materialQuestion.getName() + "</div>");
                        htmlStr.append("</div>");
                        htmlStr.append("<br />");
                    }
                }
            }
        }
        htmlStr.append("</body>");

        String html = new String(htmlStr);
        return html;
    }

    public String createContextFull(Integer id) {
        String resultURl = "";
        ExamPaper examPaper = paperMapper.selectByPrimaryKey(id);
        if (examPaper == null) {
            return resultURl;
        }
        List<Question> questionList = new ArrayList<>();
        if (examPaper.getAreas().size() > 0) {
            for (ExamPaperArea examPaperArea : examPaper.getAreas()) {
                if (examPaperArea.getRules().size() > 0) {
                    //随机出题
                    if (ExtractingStatusEnum.RANDOM.getValue().equals(examPaperArea.getExtractingStatus())) {
                        for (ExamPaperAreaRule examPaperAreaRule : examPaperArea.getRules()) {
                            List<Question> alllist = questionMapper.selectByParams(examPaperAreaRule.getQuestionBankId(), examPaperAreaRule.getQuestionType(), examPaperAreaRule.getStemType(), null, null, examPaperAreaRule.getDifficulty(), null, null, null);
                            Collections.shuffle(alllist);
                            //选取随机的集合元素
                            if (examPaperAreaRule.getQuestionCount() > alllist.size()) {
                                examPaperAreaRule.setQuestionCount(alllist.size());
                            }
                            List<Question> randomSeries = alllist.subList(0, examPaperAreaRule.getQuestionCount());
                            for (int i = 0; i < examPaperAreaRule.getQuestionCount(); i++) {
                                if (randomSeries != null && i < randomSeries.size()) {
                                    randomSeries.get(i).setGrade(examPaperAreaRule.getGrade());
                                }
                            }
                            questionList.addAll(randomSeries);
                        }
                    } else if (ExtractingStatusEnum.ORDER.getValue().equals(examPaperArea.getExtractingStatus())) {
                        //顺序出题
                        for (ExamPaperAreaRule examPaperAreaRule : examPaperArea.getRules()) {
                            List<Question> alllist = questionMapper.selectByParams(examPaperAreaRule.getQuestionBankId(), examPaperAreaRule.getQuestionType(), examPaperAreaRule.getStemType(), null, null, examPaperAreaRule.getDifficulty(), null, null, null);
                            //选取随机的集合元素
                            List<Question> randomSeries = alllist.subList(0, examPaperAreaRule.getQuestionCount());
                            for (int i = 0; i < examPaperAreaRule.getQuestionCount(); i++) {
                                if (randomSeries != null && i < randomSeries.size()) {
                                    randomSeries.get(i).setGrade(examPaperAreaRule.getGrade());
                                }
                            }
                            questionList.addAll(randomSeries);
                        }

                    } else if (ExtractingStatusEnum.AUTONOMY.getValue().equals(examPaperArea.getExtractingStatus())) {
                        questionList.addAll(questionMapper.selectByAreaId(examPaperArea.getId()));
                    }
                }
            }
        }

        StringBuffer htmlStr = new StringBuffer();
        htmlStr.append("  <meta charset=\"UTF-8\" /> \n" +
                "  <title>Title</title> \n" +
                "  <style>    * {      margin: 0;      padding: 0;      font-size: 16px;      color: #323232;      font-weight: bold;    }    html,    body {      /*height: 100%;*/    }    .contianer {      width: 500px;      padding: 15px 0 0 15px;      box-sizing: border-box;    }    .flex {      display: flex;    }    .layout_column {      display: flex;      flex-direction: column;    }    .layout_bottom {      display: flex;      align-items: flex-end;    }    .layout_center {      display: flex;      align-items: center;    }    h3 {      text-align: center;    }    .option-box {      padding: 10px 0 0 20px;      box-sizing: border-box;    }    .underline {      width: 80px;      border-bottom: 1px #323232 solid;    }  </style>\n" +
                " </head>\n" +
                "\n" +
                "<body>" +
                "\n");

        htmlStr.append("  <div class=\"contianer\">\n" +
                "    <h3>" + examPaper.getName() + "</h3>\n" +

                "    <div class=\"layout_bottom\">\n" +
                "      <span>姓名:</span>\n" +
                "      <div class=\"underline\"></div>\n" +
                "    </div>\n" +

                "    <div class=\"flex\">\n" +
                "      <span>注意事项:</span>\n" +
                "      <div class=\"layout_column\">\n" +
                "        <span>1.答题前填写好自己的姓名等信息</span>\n" +
                "<br />" +
                "        <span>2.请将答案正确填写在答题卡上</span>\n" +
                "      </div>\n" +
                "    </div>\n" +
                "    </div>\n" +
                "<br />"
        );
        int count = 0;
        for (Question question : questionList) {
            count++;
            //单选题、多选题
            if (question.getQuestionType().equals(QuestionTypeEnum.SINGLE.getValue()) || question.getQuestionType().equals(QuestionTypeEnum.MULTIPLE.getValue())) {
                List<Option> optionList = optionMapper.selectByQuestionId(question.getId());
                htmlStr.append("<div>");
                if (question.getQuestionType().equals(QuestionTypeEnum.SINGLE.getValue())) {
                    htmlStr.append("<div>" + count + ".(单选题 " + question.getGrade() + "分)" + question.getName() + "</div>");
                } else {
                    htmlStr.append("<div>" + count + ".(多选题 " + question.getGrade() + "分)" + question.getName() + "</div>");
                }

                //题目内容
                char emumOption = 'A';
                String answer = "";
                for (Option option : optionList) {
                    htmlStr.append("<div class=\"itemOption\"><span>" + emumOption + "." + option.getContent() + "</span></span></div>");

                    if (option.getIfAnswer() == true) {
                        answer += emumOption;
                    }
                    emumOption = (char) (emumOption + 1);

                }
                htmlStr.append("<div class=\"itemOption\"><span>" + "正确答案：" + answer + "</span></div>");
                htmlStr.append("</div>");
                htmlStr.append("<br />");
            }
            //判断题
            else if (question.getQuestionType().equals(QuestionTypeEnum.JUDGE.getValue())) {
                htmlStr.append("<div>");
                htmlStr.append("<div>" + count + ".(判断题 " + question.getGrade() + "分)" + question.getName() + "</div>" +
                        "<div class=\"option-box layout_column\">\n" +
                        "        <span>A.对</span>\n" +
                        "        <span>B.错</span>\n" +
                        "      </div>");
                if (question.getJudgmentAnswer() == true) {
                    htmlStr.append("<div class=\"itemOption\"><span>" + "正确答案：" + "正确" + "</span></div>");

                } else {
                    htmlStr.append("<div class=\"itemOption\"><span>" + "正确答案：" + "错误" + "</span></div>");

                }
                htmlStr.append("</div>");
                htmlStr.append("<br />");
            }
            //填空题
            else if (question.getQuestionType().equals(QuestionTypeEnum.GAP.getValue())) {
                htmlStr.append("<div>");
                htmlStr.append("<div>" + count + ".(填空题 " + question.getGrade() + "分)" + question.getName() + "</div>");
                htmlStr.append("<div class=\"itemOption\"><span>" + "正确答案：" + question.getQuestionAnswer() + "</span></div>");

                htmlStr.append("</div>");
                htmlStr.append("<br />");
            }

            //问答题
            else if (question.getQuestionType().equals(QuestionTypeEnum.ESSAY.getValue())) {
                htmlStr.append("<div>");
                htmlStr.append("<div>" + count + ".(问答题 " + question.getGrade() + "分)" + question.getName() + "</div>");
                htmlStr.append("<div class=\"itemOption\"><span>" + "正确答案：" + question.getQuestionAnswer() + "</span></div>");
                htmlStr.append("</div>");
                htmlStr.append("<br />");
            }
            //材料题
            else if (question.getQuestionType().equals(QuestionTypeEnum.MATERIALS.getValue())) {
                //材料题题目内容
                htmlStr.append("<div class=\"paddingTop\"><span><p>" + count + ".(材料题 " + question.getGrade() + "分)" + question.getName() + "</p></span></div>");

                //材料题子题目（判断、单选、多选、问答、填空）
                List<Question> list = questionMapper.selectByParams(null, null, null, null, null, null, question.getId(), null, null);

                int p = 0;
                for (Question materialQuestion : list) {
                    p++;
                    //单选题、多选题
                    if (materialQuestion.getQuestionType().equals(QuestionTypeEnum.SINGLE.getValue()) || materialQuestion.getQuestionType().equals(QuestionTypeEnum.MULTIPLE.getValue())) {
                        htmlStr.append("<div>");

                        if (materialQuestion.getQuestionType().equals(QuestionTypeEnum.SINGLE.getValue())) {

                            htmlStr.append("<div >" + p + ".(单选题 " + materialQuestion.getGrade() + "分)" + materialQuestion.getName() + "</div>");
                        } else {
                            htmlStr.append("<div >" + p + ".(多选题 " + materialQuestion.getGrade() + "分)" + materialQuestion.getName() + "</div>");
                        }
                        //题目选项集合
                        List<Option> optionList = optionMapper.selectByQuestionId(materialQuestion.getId());

                        char emumOption = 'A';
                        String answer = "";
                        for (Option option : optionList) {
                            htmlStr.append("<div class=\"itemOption\"><span>" + emumOption + "." + option.getContent() + "</span></span></div>");

                            if (option.getIfAnswer() == true) {
                                answer += emumOption;
                            }
                            emumOption = (char) (emumOption + 1);

                        }
                        htmlStr.append("<div class=\"itemOption\"><span>" + "正确答案：" + answer + "</span></div>");
                        htmlStr.append("</div>\n");
                        htmlStr.append("<br />");

                    } else if (materialQuestion.getQuestionType().equals(QuestionTypeEnum.JUDGE.getValue())) {

                        htmlStr.append("<div>" + p + ".(判断题 " + materialQuestion.getGrade() + "分)" + materialQuestion.getName() + "</div>" +
                                "<div class=\"option-box layout_column\">\n" +
                                "        <span>A.对</span>\n" +
                                "        <span>B.错</span>\n" +
                                "      </div>");
                        if (materialQuestion.getJudgmentAnswer() == true) {
                            htmlStr.append("<div class=\"itemOption\"><span>" + "正确答案：" + "正确" + "</span></div>");

                        } else {
                            htmlStr.append("<div class=\"itemOption\"><span>" + "正确答案：" + "错误" + "</span></div>");

                        }
                        htmlStr.append("</div>");
                        htmlStr.append("<br />");
                    }
                    //填空题
                    else if (materialQuestion.getQuestionType().equals(QuestionTypeEnum.GAP.getValue())) {
                        htmlStr.append("<div>");
                        htmlStr.append("<div>" + p + ".(填空题 " + materialQuestion.getGrade() + "分)" + materialQuestion.getName() + "</div>");
                        htmlStr.append("<div class=\"itemOption\"><span>" + "正确答案：" + materialQuestion.getQuestionAnswer() + "</span></div>");

                        htmlStr.append("</div>");
                        htmlStr.append("<br />");
                    }
                    //问答题
                    else if (materialQuestion.getQuestionType().equals(QuestionTypeEnum.ESSAY.getValue())) {
                        htmlStr.append("<div>");
                        htmlStr.append("<div>" + p + ".(问答题 " + materialQuestion.getGrade() + "分)" + materialQuestion.getName() + "</div>");
                        htmlStr.append("<div class=\"itemOption\"><span>" + "正确答案：" + materialQuestion.getQuestionAnswer() + "</span></div>");

                        htmlStr.append("</div>");
                        htmlStr.append("<br />");
                    }
                }
            }
        }
        htmlStr.append("</body>");
        String html = new String(htmlStr);
        return html;
    }

    /**
     * 导出全部学员考卷
     * examId 考试id
     *
     * @return
     */
    @Override
    public String exportTrainingOrganizationExam(TrainingOrganizationExamDto dto) {
        String resultURl = "";
        List<StringBuffer> htmlStrList = new ArrayList<>();

        //考卷名称集合（命名规则：排序值+考试名称+考生姓名）
        List<String> studentNameList = new ArrayList<>();
        if (dto.getStudentExamIdList() != null && dto.getStudentExamIdList().size() > 0) {
            for (int i = 0; i < dto.getStudentExamIdList().size(); i++) {
                StudentExamVo studentExamVo = studentExamMapper.selectById(dto.getStudentExamIdList().get(i));

                //根据学员考试id获取学员考试试卷
                StudentExamPaperVo result = studentExamQuestionService.fetchQuestionsByStudentExamId(dto.getStudentExamIdList().get(i));
                StringBuffer htmlStr = new StringBuffer();
                htmlStr.append("  <meta charset=\"UTF-8\" /> \n" +
                        "  <title>Title</title> \n" +
                        "  <style>    * {      margin: 0;      padding: 0;      font-size: 16px;      color: #323232;      font-weight: bold;    }    html,    body {      /*height: 100%;*/    }    .contianer {      width: 500px;      padding: 15px 0 0 15px;      box-sizing: border-box;    }    .flex {      display: flex;    }    .layout_column {      display: flex;      flex-direction: column;    }    .layout_bottom {      display: flex;      align-items: flex-end;    }    .layout_center {      display: flex;      align-items: center;    }    h3 {      text-align: center;    }    .option-box {      padding: 10px 0 0 20px;      box-sizing: border-box;    }    .underline {      width: 80px;      border-bottom: 1px #323232 solid;    }  </style>\n" +
                        " </head>\n" +
                        "\n" +
                        "<body>" +
                        "\n");

                htmlStr.append("  <div class=\"contianer\">\n" +
                        "    <h3>" + result.getTitle() + "</h3>\n" +

                        "    <div class=\"layout_bottom\">\n" +
                        "      <span>姓名:</span>\n" + studentExamVo.getStudentName() +
                        "      <div class=\"underline\"></div>\n" +
                        "    </div>\n" +

                        "    <div class=\"flex\">\n" +
                        "      <span>注意事项:</span>\n" +
                        "      <div class=\"layout_column\">\n" +
                        "        <span>1.答题前填写好自己的姓名等信息</span>\n" +
                        "<br />" +
                        "        <span>2.请将答案正确填写在答题卡上</span>\n" +
                        "      </div>\n" +
                        "    </div>\n" +
                        "    </div>\n" +
                        "<br />"
                );


                int count = 0;
                for (StudentExamAreaVo studentExamAreaVo : result.getAreas()) {

                    for (StudentExamQuestionVo studentExamQuestionVo : studentExamAreaVo.getQuestions()) {
                        count++;
                        //单选题、多选题
                        if (studentExamQuestionVo.getQuestionType().equals(QuestionTypeEnum.SINGLE.getValue()) || studentExamQuestionVo.getQuestionType().equals(QuestionTypeEnum.MULTIPLE.getValue())) {
                            //单选题、多选题
                            if (studentExamQuestionVo.getQuestionType().equals(QuestionTypeEnum.SINGLE.getValue())) {
                                htmlStr.append("<div>" + count + ".(单选题 " + studentExamQuestionVo.getScore() + "分)" + studentExamQuestionVo.getTitle() + "</div>");
                            } else {
                                htmlStr.append("<div>" + count + ".(多选题 " + studentExamQuestionVo.getScore() + "分)" + studentExamQuestionVo.getTitle() + "</div>");
                            }
                            List<Option> optionList = optionMapper.selectByQuestionId(studentExamQuestionVo.getQuestionId());
                            char emumOption = 'A';
                            for (Option option : optionList) {
                                htmlStr.append("<div class=\"itemOption\"><span>" + emumOption + "." + option.getContent() + "</span></div>");

                                htmlStr.append("<br />");
                                emumOption = (char) (emumOption + 1);

                            }
                            if (studentExamQuestionVo.getAnswer() == null) {
                                htmlStr.append("<div class=\"itemOption\"><span>" + "考生答案：     " + "</span></div>");

                            } else {
                                String ans = "";
                                List<Integer> submitAnswers = JSON.parseArray(studentExamQuestionVo.getAnswer(), Integer.class);

                                for (int j = 0; j < submitAnswers.size(); j++) {
                                    emumOption = 'A';
                                    for (Option option : optionList) {
                                        if (option.getId().equals(submitAnswers.get(j))) {
                                            ans += emumOption;
                                            break;
                                        }
                                        emumOption = (char) (emumOption + 1);
                                    }
                                }
                                htmlStr.append("<div class=\"itemOption\"><span>" + "考生答案：" + ans + "</span></div>");

                            }

                            String ansb = "";
                            emumOption = 'A';
                            for (Option option : optionList) {
                                if (option.getIfAnswer()) {
                                    ansb += emumOption;
                                }
                                emumOption = (char) (emumOption + 1);
                            }
                            htmlStr.append("<div class=\"itemOption\"><span>" + "标准答案：" + ansb + "</span></div>");

                            htmlStr.append("<br />");

                        }
                        //判断题
                        else if (studentExamQuestionVo.getQuestionType().equals(QuestionTypeEnum.JUDGE.getValue())) {
                            htmlStr.append("<div>");
                            htmlStr.append("<div>" + count + ".(判断题 " + studentExamQuestionVo.getScore() + "分)" + studentExamQuestionVo.getTitle() + "</div>" +
                                    "<div class=\"option-box layout_column\">\n" +
                                    "        <span>A.对</span>\n" +
                                    "        <span>B.错</span>\n" +
                                    "      </div>");
                            List<Integer> submitAnswers = JSON.parseArray(studentExamQuestionVo.getAnswer(), Integer.class);

                            if (submitAnswers == null || submitAnswers.size() == 0) {
                                htmlStr.append("<div class=\"itemOption\"><span>" + "考生答案：      " + "</span></div>");
                            } else if (submitAnswers.get(0) == 1) {
                                htmlStr.append("<div class=\"itemOption\"><span>" + "考生答案：" + "对" + "</span></div>");

                            } else {
                                htmlStr.append("<div class=\"itemOption\"><span>" + "考生答案：" + "错" + "</span></div>");

                            }
                            if (studentExamQuestionVo.getJudgmentAnswer() == true) {
                                htmlStr.append("<div class=\"itemOption\"><span>" + "正确答案：" + "对" + "</span></div>");

                            } else {
                                htmlStr.append("<div class=\"itemOption\"><span>" + "正确答案：" + "错" + "</span></div>");

                            }
                            htmlStr.append("</div>");
                            htmlStr.append("<br />");
                        }
                        //填空题
                        else if (studentExamQuestionVo.getQuestionType().equals(QuestionTypeEnum.GAP.getValue())) {
                            htmlStr.append("<div>" + count + ".(填空题 " + studentExamQuestionVo.getScore() + "分)" + studentExamQuestionVo.getTitle() + "</div>");
                            if (studentExamQuestionVo.getSubjectiveAnswer() == null) {
                                htmlStr.append("<div class=\"itemOption\"><span>" + "考生答案：      " + "</span></div>");

                            } else {
                                htmlStr.append("<div class=\"itemOption\"><span>" + "考生答案：" + studentExamQuestionVo.getSubjectiveAnswer() + "</span></div>");
                            }

                            htmlStr.append("<div class=\"itemOption\"><span>" + "标准答案：" + studentExamQuestionVo.getQuestionAnswer() + "</span></div>");
                            htmlStr.append("<br />");
                        }
                        //问答题
                        else if (studentExamQuestionVo.getQuestionType().equals(QuestionTypeEnum.ESSAY.getValue())) {
                            htmlStr.append("<div >" + count + ".(问答题 " + studentExamQuestionVo.getScore() + "分)" + studentExamQuestionVo.getTitle() + "</div>");
                            if (studentExamQuestionVo.getSubjectiveAnswer() == null) {
                                htmlStr.append("<div class=\"itemOption\"><span>" + "考生答案：      " + "</p>\n" + "</span></div>");

                            } else {
                                htmlStr.append("<div class=\"itemOption\"><span>" + "考生答案：" + studentExamQuestionVo.getSubjectiveAnswer() + "</span></div>");
                            }
                            htmlStr.append("<div class=\"itemOption\"><span>" + "标准答案：" + studentExamQuestionVo.getQuestionAnswer() + "</span></div>");
                            htmlStr.append("<br />");
                        }
                        //材料题
                        else if (studentExamQuestionVo.getQuestionType().equals(QuestionTypeEnum.MATERIALS.getValue())) {

                            //材料题题目内容
                            htmlStr.append("<div>" + count + ".(材料题)" + studentExamQuestionVo.getTitle() + "</div>");

                            //材料题子题目（判断、单选、多选、问答、填空）
                            List<StudentExamQuestionVo> list = studentExamQuestionVo.getStudentExamQuestionVo();
                            if (list != null && list.size() > 0) {
                                int p = 0;
                                for (StudentExamQuestionVo materialQuestion : list) {
                                    p++;
                                    //单选题、多选题
                                    if (materialQuestion.getQuestionType().equals(QuestionTypeEnum.SINGLE.getValue()) || materialQuestion.getQuestionType().equals(QuestionTypeEnum.MULTIPLE.getValue())) {
                                        //题目内容
                                        if (materialQuestion.getQuestionType().equals(QuestionTypeEnum.SINGLE.getValue())) {

                                            htmlStr.append("<div class=\"paddingTop\"><span>" + p + ".(单选题 " + materialQuestion.getScore() + "分)" + materialQuestion.getTitle() + "</span></div>");
                                        } else {
                                            htmlStr.append("<div class=\"paddingTop\"><span>" + p + ".(多选题 " + materialQuestion.getScore() + "分)" + materialQuestion.getTitle() + "</span></div>");
                                        }

                                        List<Option> optionList = optionMapper.selectByQuestionId(materialQuestion.getQuestionId());

                                        char emumOption = 'A';
                                        for (Option option : optionList) {
                                            htmlStr.append("<div class=\"itemOption\"><span>" + emumOption + "." + option.getContent() + "</span></div>");
                                            emumOption = (char) (emumOption + 1);

                                        }
                                        if (materialQuestion.getAnswer() == null) {
                                            htmlStr.append("<div class=\"paddingTop\">" + "考生答案：     " + "</div>");
                                        } else {
                                            String ans = "";
                                            List<Integer> submitAnswers = JSON.parseArray(materialQuestion.getAnswer(), Integer.class);

                                            for (int j = 0; j < submitAnswers.size(); j++) {
                                                emumOption = 'A';
                                                for (Option option : optionList) {
                                                    if (option.getId().equals(submitAnswers.get(j))) {
                                                        ans += emumOption;
                                                        break;
                                                    }
                                                    emumOption = (char) (emumOption + 1);
                                                }
                                            }
                                            htmlStr.append("<div class=\"paddingTop\">" + "考生答案：" + ans + "</div>");

                                        }
                                        String ansb = "";
                                        emumOption = 'A';
                                        for (Option option : optionList) {
                                            if (option.getIfAnswer()) {
                                                ansb += emumOption;
                                            }
                                            emumOption = (char) (emumOption + 1);
                                        }
                                        htmlStr.append("<div class=\"paddingTop\">" + "标准答案：" + ansb + "</div>");
                                        htmlStr.append("<br />");

                                    }

                                    //判断题
                                    else if (materialQuestion.getQuestionType().equals(QuestionTypeEnum.JUDGE.getValue())) {

                                        htmlStr.append("<div class=\"itemOption\"><span>" + p + ".(判断题 " + materialQuestion.getScore() + "分)" + materialQuestion.getTitle() +
                                                "<p>A.对</p>\n" +
                                                "<p>B.错</p>\n" +
                                                "\n" +
                                                "\n" +
                                                "</span></div>");

                                        List<Integer> submitAnswers = JSON.parseArray(materialQuestion.getAnswer(), Integer.class);
                                        if (submitAnswers == null || submitAnswers.size() == 0) {
                                            htmlStr.append("<div class=\"itemOption\"><span>" + "考生答案：" + "未选" + "</span></div>");
                                        } else if (submitAnswers.get(0) == 1) {
                                            htmlStr.append("<div class=\"itemOption\"><span>" + "考生答案：" + "对" + "</span></div>");

                                        } else {
                                            htmlStr.append("<div class=\"itemOption\"><span>" + "考生答案：" + "错" + " </span></div>");

                                        }
                                        if (materialQuestion.getJudgmentAnswer() == true) {
                                            htmlStr.append("<div class=\"itemOption\"><span>" + "标准答案：" + "对" + "</span></div>");

                                        } else {
                                            htmlStr.append("<div class=\"itemOption\"><span>" + "标准答案：" + "错" + "</span></div>");

                                        }
                                        htmlStr.append("<br />");

                                    }
                                    //填空题
                                    else if (materialQuestion.getQuestionType().equals(QuestionTypeEnum.GAP.getValue())) {
                                        htmlStr.append("<div class=\"itemOption\"><span><p>" + p + ".(填空题 " + materialQuestion.getScore() + "分)" + "</p>\n" + materialQuestion.getTitle() + "</span></div>");
                                        if (materialQuestion.getSubjectiveAnswer() == null) {
                                            htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "考生答案：未答 " + "</p>\n" + "</span></span></div>");

                                        } else {
                                            htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "考生答案：" + materialQuestion.getSubjectiveAnswer() + "</p>\n" + "</span></span></div>");
                                        }
                                        htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "标准答案：" + materialQuestion.getQuestionAnswer() + "</p>\n" + "</span></span></div>");
                                        htmlStr.append("<br />");

                                    }
                                    //问答题
                                    else if (materialQuestion.getQuestionType().equals(QuestionTypeEnum.ESSAY.getValue())) {
                                        htmlStr.append("<div class=\"itemOption\"><span><p>" + p + ".(问答题 " + materialQuestion.getScore() + "分)" + "</p>\n" + materialQuestion.getTitle() + "</span></div>");

                                        if (materialQuestion.getSubjectiveAnswer() == null) {
                                            htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "考生答案：未答" + "</p>\n" + "</span></span></div>");

                                        } else {
                                            htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "考生答案：" + materialQuestion.getSubjectiveAnswer() + "</p>\n" + "</span></span></div>");
                                        }

                                        htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "标准答案：" + materialQuestion.getQuestionAnswer() + "</p>\n" + "</span></span></div>");
                                        htmlStr.append("<br />");

                                    }
                                }

                            }

                        }
                    }
                }
                htmlStr.append("</body>");
                htmlStrList.add(i, htmlStr);
                String name = "(" + i + ")" + result.getTitle() + studentExamVo.getStudentName();
                studentNameList.add(i, name);
            }
        }

        File[] srcFiles = new File[dto.getStudentExamIdList().size()];
        int count = 0;
        for (StringBuffer htmlStr : htmlStrList) {

            try {
                String html = new String(htmlStr);


                String context = HtmlText.WORD_HEAD + ImageProcessUtil.processImage(html) + HtmlText.WORD_FOOT;
                byte[] b = context.getBytes(StandardCharsets.UTF_8);
                //将字节数组包装到流中
                InputStream inputStream = new ByteArrayInputStream(b);

                long l = System.currentTimeMillis();

                String newFileName = word + studentNameList.get(count) + ".doc";

                File file = new File(newFileName);
                try {
                    // 创建新的文件，前提是必须文件夹已经存在，即D:/File已经存在，文件夹名字不区分大小写：
                    file.createNewFile();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                OutputStream outputStream1 = Files.newOutputStream(Paths.get(newFileName));
                Html2Word poiConvert = new ConvertByPoi(inputStream, outputStream1);
                poiConvert.convert();
                log.info("poi方式导出用时:{}ms", System.currentTimeMillis() - l);
                srcFiles[count++] = file;
                IOUtils.closeQuietly(inputStream);
                IOUtils.closeQuietly(outputStream1);
                //删除本地的试卷
//                file.delete();

            } catch (IOException e) {
                e.printStackTrace();
            }

        }

        try {
            File zipFile = new File(word + "ZipFile.zip");
            // 调用压缩方法
            zipFiles(srcFiles, zipFile);
            //file转MultipartFile
            FileInputStream input = new FileInputStream(zipFile);
            MultipartFile multipartFile = new MockMultipartFile("file", zipFile.getName(), "text/plain", IOUtils.toByteArray(input));
            String random = UUID.randomUUID().toString().replace("-", "");

            String objectName = random + "(全部考卷)";

            //上传压缩包到Oss服务器
            resultURl = bosService.putObject(multipartFile, objectName);

            IOUtils.closeQuietly(input);
            zipFile.delete();
            for (File t : srcFiles) {
                deleteFile(t.getAbsolutePath());
//                boolean mark= t.delete();
            }
        } catch (IOException e) {
            log.error("上传压缩包文件失败！", e.getMessage());
        }


        //返回考卷url集合
        return resultURl;
    }


    /**
     * 导出全部学员考卷
     * examId 考试id
     *
     * @return
     */
    @Override
    public String exportExam(Integer examId) {
        String resultURl = "";
        List<StringBuffer> htmlStrList = new ArrayList<>();

        Exam exam = examMapper.selectByPrimaryKey(examId);

        //考卷名称集合（命名规则：排序值+考试名称+考生姓名）
        List<String> studentNameList = new ArrayList<>();
        List<StudentExam> studentExamList = studentExamMapper.selectStudentExambyExamId(examId);
        if (studentExamList != null && studentExamList.size() > 0) {
            for (int i = 0; i < studentExamList.size(); i++) {
                StudentExamVo studentExamVo = studentExamMapper.selectById(studentExamList.get(i).getId());

                //根据学员考试id获取学员考试试卷
                StudentExamPaperVo result = studentExamQuestionService.fetchQuestionsByStudentExamId(studentExamList.get(i).getId());
                StringBuffer htmlStr = new StringBuffer();
                htmlStr.append("  <meta charset=\"UTF-8\" /> \n" +
                        "  <title>Title</title> \n" +
                        "  <style>    * {      margin: 0;      padding: 0;      font-size: 16px;      color: #323232;      font-weight: bold;    }    html,    body {      /*height: 100%;*/    }    .contianer {      width: 500px;      padding: 15px 0 0 15px;      box-sizing: border-box;    }    .flex {      display: flex;    }    .layout_column {      display: flex;      flex-direction: column;    }    .layout_bottom {      display: flex;      align-items: flex-end;    }    .layout_center {      display: flex;      align-items: center;    }    h3 {      text-align: center;    }    .option-box {      padding: 10px 0 0 20px;      box-sizing: border-box;    }    .underline {      width: 80px;      border-bottom: 1px #323232 solid;    }  </style>\n" +
                        " </head>\n" +
                        "\n" +
                        "<body>" +
                        "\n");

                htmlStr.append("  <div class=\"contianer\">\n" +
                        "    <h3>" + result.getTitle() + "</h3>\n" +

                        "    <div class=\"layout_bottom\">\n" +
                        "      <span>姓名:</span>\n" + studentExamVo.getStudentName() +
                        "      <div class=\"underline\"></div>\n" +
                        "    </div>\n" +

                        "    <div class=\"flex\">\n" +
                        "      <span>注意事项:</span>\n" +
                        "      <div class=\"layout_column\">\n" +
                        "        <span>1.答题前填写好自己的姓名等信息</span>\n" +
                        "<br />" +
                        "        <span>2.请将答案正确填写在答题卡上</span>\n" +
                        "      </div>\n" +
                        "    </div>\n" +
                        "    </div>\n" +
                        "<br />"
                );


                int count = 0;
                for (StudentExamAreaVo studentExamAreaVo : result.getAreas()) {

                    for (StudentExamQuestionVo studentExamQuestionVo : studentExamAreaVo.getQuestions()) {
                        count++;
                        //单选题、多选题
                        if (studentExamQuestionVo.getQuestionType().equals(QuestionTypeEnum.SINGLE.getValue()) || studentExamQuestionVo.getQuestionType().equals(QuestionTypeEnum.MULTIPLE.getValue())) {
                            //单选题、多选题
                            if (studentExamQuestionVo.getQuestionType().equals(QuestionTypeEnum.SINGLE.getValue())) {
                                htmlStr.append("<div>" + count + ".(单选题 " + studentExamQuestionVo.getScore() + "分)" + studentExamQuestionVo.getTitle() + "</div>");
                            } else {
                                htmlStr.append("<div>" + count + ".(多选题 " + studentExamQuestionVo.getScore() + "分)" + studentExamQuestionVo.getTitle() + "</div>");
                            }
                            List<Option> optionList = optionMapper.selectByQuestionId(studentExamQuestionVo.getQuestionId());
                            char emumOption = 'A';
                            for (Option option : optionList) {
                                htmlStr.append("<div class=\"itemOption\"><span>" + emumOption + "." + option.getContent() + "</span></div>");

                                htmlStr.append("<br />");
                                emumOption = (char) (emumOption + 1);

                            }
                            if (studentExamQuestionVo.getAnswer() == null) {
                                htmlStr.append("<div class=\"itemOption\"><span>" + "考生答案：     " + "</span></div>");

                            } else {
                                String ans = "";
                                List<Integer> submitAnswers = JSON.parseArray(studentExamQuestionVo.getAnswer(), Integer.class);

                                for (int j = 0; j < submitAnswers.size(); j++) {
                                    emumOption = 'A';
                                    for (Option option : optionList) {
                                        if (option.getId().equals(submitAnswers.get(j))) {
                                            ans += emumOption;
                                            break;
                                        }
                                        emumOption = (char) (emumOption + 1);
                                    }
                                }
                                htmlStr.append("<div class=\"itemOption\"><span>" + "考生答案：" + ans + "</span></div>");

                            }

                            String ansb = "";
                            emumOption = 'A';
                            for (Option option : optionList) {
                                if (option.getIfAnswer()) {
                                    ansb += emumOption;
                                }
                                emumOption = (char) (emumOption + 1);
                            }
                            htmlStr.append("<div class=\"itemOption\"><span>" + "标准答案：" + ansb + "</span></div>");

                            htmlStr.append("<br />");

                        }
                        //判断题
                        else if (studentExamQuestionVo.getQuestionType().equals(QuestionTypeEnum.JUDGE.getValue())) {
                            htmlStr.append("<div>");
                            htmlStr.append("<div>" + count + ".(判断题 " + studentExamQuestionVo.getScore() + "分)" + studentExamQuestionVo.getTitle() + "</div>" +
                                    "<div class=\"option-box layout_column\">\n" +
                                    "        <span>A.对</span>\n" +
                                    "        <span>B.错</span>\n" +
                                    "      </div>");
                            List<Integer> submitAnswers = JSON.parseArray(studentExamQuestionVo.getAnswer(), Integer.class);

                            if (submitAnswers == null || submitAnswers.size() == 0) {
                                htmlStr.append("<div class=\"itemOption\"><span>" + "考生答案：      " + "</span></div>");
                            } else if (submitAnswers.get(0) == 1) {
                                htmlStr.append("<div class=\"itemOption\"><span>" + "考生答案：" + "对" + "</span></div>");

                            } else {
                                htmlStr.append("<div class=\"itemOption\"><span>" + "考生答案：" + "错" + "</span></div>");

                            }
                            if (studentExamQuestionVo.getJudgmentAnswer() == true) {
                                htmlStr.append("<div class=\"itemOption\"><span>" + "正确答案：" + "对" + "</span></div>");

                            } else {
                                htmlStr.append("<div class=\"itemOption\"><span>" + "正确答案：" + "错" + "</span></div>");

                            }
                            htmlStr.append("</div>");
                            htmlStr.append("<br />");
                        }
                        //填空题
                        else if (studentExamQuestionVo.getQuestionType().equals(QuestionTypeEnum.GAP.getValue())) {
                            htmlStr.append("<div>" + count + ".(填空题 " + studentExamQuestionVo.getScore() + "分)" + studentExamQuestionVo.getTitle() + "</div>");
                            if (studentExamQuestionVo.getSubjectiveAnswer() == null) {
                                htmlStr.append("<div class=\"itemOption\"><span>" + "考生答案：      " + "</span></div>");

                            } else {
                                htmlStr.append("<div class=\"itemOption\"><span>" + "考生答案：" + studentExamQuestionVo.getSubjectiveAnswer() + "</span></div>");
                            }

                            htmlStr.append("<div class=\"itemOption\"><span>" + "标准答案：" + studentExamQuestionVo.getQuestionAnswer() + "</span></div>");
                            htmlStr.append("<br />");
                        }
                        //问答题
                        else if (studentExamQuestionVo.getQuestionType().equals(QuestionTypeEnum.ESSAY.getValue())) {
                            htmlStr.append("<div >" + count + ".(问答题 " + studentExamQuestionVo.getScore() + "分)" + studentExamQuestionVo.getTitle() + "</div>");
                            if (studentExamQuestionVo.getSubjectiveAnswer() == null) {
                                htmlStr.append("<div class=\"itemOption\"><span>" + "考生答案：      " + "</p>\n" + "</span></div>");

                            } else {
                                htmlStr.append("<div class=\"itemOption\"><span>" + "考生答案：" + studentExamQuestionVo.getSubjectiveAnswer() + "</span></div>");
                            }
                            htmlStr.append("<div class=\"itemOption\"><span>" + "标准答案：" + studentExamQuestionVo.getQuestionAnswer() + "</span></div>");
                            htmlStr.append("<br />");
                        }
                        //材料题
                        else if (studentExamQuestionVo.getQuestionType().equals(QuestionTypeEnum.MATERIALS.getValue())) {

                            //材料题题目内容
                            htmlStr.append("<div>" + count + ".(材料题)" + studentExamQuestionVo.getTitle() + "</div>");

                            //材料题子题目（判断、单选、多选、问答、填空）
                            List<StudentExamQuestionVo> list = studentExamQuestionVo.getStudentExamQuestionVo();
                            if (list != null && list.size() > 0) {
                                int p = 0;
                                for (StudentExamQuestionVo materialQuestion : list) {
                                    p++;
                                    //单选题、多选题
                                    if (materialQuestion.getQuestionType().equals(QuestionTypeEnum.SINGLE.getValue()) || materialQuestion.getQuestionType().equals(QuestionTypeEnum.MULTIPLE.getValue())) {
                                        //题目内容
                                        if (materialQuestion.getQuestionType().equals(QuestionTypeEnum.SINGLE.getValue())) {

                                            htmlStr.append("<div class=\"paddingTop\"><span>" + p + ".(单选题 " + materialQuestion.getScore() + "分)" + materialQuestion.getTitle() + "</span></div>");
                                        } else {
                                            htmlStr.append("<div class=\"paddingTop\"><span>" + p + ".(多选题 " + materialQuestion.getScore() + "分)" + materialQuestion.getTitle() + "</span></div>");
                                        }

                                        List<Option> optionList = optionMapper.selectByQuestionId(materialQuestion.getQuestionId());

                                        char emumOption = 'A';
                                        for (Option option : optionList) {
                                            htmlStr.append("<div class=\"itemOption\"><span>" + emumOption + "." + option.getContent() + "</span></div>");
                                            emumOption = (char) (emumOption + 1);

                                        }
                                        if (materialQuestion.getAnswer() == null) {
                                            htmlStr.append("<div class=\"paddingTop\">" + "考生答案：     " + "</div>");
                                        } else {
                                            String ans = "";
                                            List<Integer> submitAnswers = JSON.parseArray(materialQuestion.getAnswer(), Integer.class);

                                            for (int j = 0; j < submitAnswers.size(); j++) {
                                                emumOption = 'A';
                                                for (Option option : optionList) {
                                                    if (option.getId().equals(submitAnswers.get(j))) {
                                                        ans += emumOption;
                                                        break;
                                                    }
                                                    emumOption = (char) (emumOption + 1);
                                                }
                                            }
                                            htmlStr.append("<div class=\"paddingTop\">" + "考生答案：" + ans + "</div>");

                                        }
                                        String ansb = "";
                                        emumOption = 'A';
                                        for (Option option : optionList) {
                                            if (option.getIfAnswer()) {
                                                ansb += emumOption;
                                            }
                                            emumOption = (char) (emumOption + 1);
                                        }
                                        htmlStr.append("<div class=\"paddingTop\">" + "标准答案：" + ansb + "</div>");
                                        htmlStr.append("<br />");

                                    }

                                    //判断题
                                    else if (materialQuestion.getQuestionType().equals(QuestionTypeEnum.JUDGE.getValue())) {

                                        htmlStr.append("<div class=\"itemOption\"><span>" + p + ".(判断题 " + materialQuestion.getScore() + "分)" + materialQuestion.getTitle() +
                                                "<p>A.对</p>\n" +
                                                "<p>B.错</p>\n" +
                                                "\n" +
                                                "\n" +
                                                "</span></div>");

                                        List<Integer> submitAnswers = JSON.parseArray(materialQuestion.getAnswer(), Integer.class);
                                        if (submitAnswers == null || submitAnswers.size() == 0) {
                                            htmlStr.append("<div class=\"itemOption\"><span>" + "考生答案：" + "未选" + "</span></div>");
                                        } else if (submitAnswers.get(0) == 1) {
                                            htmlStr.append("<div class=\"itemOption\"><span>" + "考生答案：" + "对" + "</span></div>");

                                        } else {
                                            htmlStr.append("<div class=\"itemOption\"><span>" + "考生答案：" + "错" + " </span></div>");

                                        }
                                        if (materialQuestion.getJudgmentAnswer() == true) {
                                            htmlStr.append("<div class=\"itemOption\"><span>" + "标准答案：" + "对" + "</span></div>");

                                        } else {
                                            htmlStr.append("<div class=\"itemOption\"><span>" + "标准答案：" + "错" + "</span></div>");

                                        }
                                        htmlStr.append("<br />");

                                    }
                                    //填空题
                                    else if (materialQuestion.getQuestionType().equals(QuestionTypeEnum.GAP.getValue())) {
                                        htmlStr.append("<div class=\"itemOption\"><span><p>" + p + ".(填空题 " + materialQuestion.getScore() + "分)" + "</p>\n" + materialQuestion.getTitle() + "</span></div>");
                                        if (materialQuestion.getSubjectiveAnswer() == null) {
                                            htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "考生答案：未答 " + "</p>\n" + "</span></span></div>");

                                        } else {
                                            htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "考生答案：" + materialQuestion.getSubjectiveAnswer() + "</p>\n" + "</span></span></div>");
                                        }
                                        htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "标准答案：" + materialQuestion.getQuestionAnswer() + "</p>\n" + "</span></span></div>");
                                        htmlStr.append("<br />");

                                    }
                                    //问答题
                                    else if (materialQuestion.getQuestionType().equals(QuestionTypeEnum.ESSAY.getValue())) {
                                        htmlStr.append("<div class=\"itemOption\"><span><p>" + p + ".(问答题 " + materialQuestion.getScore() + "分)" + "</p>\n" + materialQuestion.getTitle() + "</span></div>");

                                        if (materialQuestion.getSubjectiveAnswer() == null) {
                                            htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "考生答案：未答" + "</p>\n" + "</span></span></div>");

                                        } else {
                                            htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "考生答案：" + materialQuestion.getSubjectiveAnswer() + "</p>\n" + "</span></span></div>");
                                        }

                                        htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "标准答案：" + materialQuestion.getQuestionAnswer() + "</p>\n" + "</span></span></div>");
                                        htmlStr.append("<br />");

                                    }
                                }

                            }

                        }
                    }
                }
                htmlStr.append("</body>");
                htmlStrList.add(i, htmlStr);
                String name = "(" + i + ")" + result.getTitle() + studentExamVo.getStudentName();
                studentNameList.add(i, name);
            }
        }

        File[] srcFiles = new File[studentExamList.size()];
        int count = 0;
        for (StringBuffer htmlStr : htmlStrList) {

            try {
                String html = new String(htmlStr);


                String context = HtmlText.WORD_HEAD + ImageProcessUtil.processImage(html) + HtmlText.WORD_FOOT;
                byte[] b = context.getBytes(StandardCharsets.UTF_8);
                //将字节数组包装到流中
                InputStream inputStream = new ByteArrayInputStream(b);

                long l = System.currentTimeMillis();

                String newFileName = word + studentNameList.get(count) + ".doc";

                File file = new File(newFileName);
                try {
                    // 创建新的文件，前提是必须文件夹已经存在，即D:/File已经存在，文件夹名字不区分大小写：
                    file.createNewFile();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                OutputStream outputStream1 = Files.newOutputStream(Paths.get(newFileName));
                Html2Word poiConvert = new ConvertByPoi(inputStream, outputStream1);
                poiConvert.convert();
                log.info("poi方式导出用时:{}ms", System.currentTimeMillis() - l);
                srcFiles[count++] = file;
                IOUtils.closeQuietly(inputStream);
                IOUtils.closeQuietly(outputStream1);
                //删除本地的试卷
//                file.delete();

            } catch (IOException e) {
                e.printStackTrace();
            }

        }

        try {
            File zipFile = new File(word + "ZipFile.zip");
            // 调用压缩方法
            zipFiles(srcFiles, zipFile);
            //file转MultipartFile
            FileInputStream input = new FileInputStream(zipFile);
            MultipartFile multipartFile = new MockMultipartFile("file", zipFile.getName(), "text/plain", IOUtils.toByteArray(input));
            String random = UUID.randomUUID().toString().replace("-", "");

            String objectName = exam.getName() + "(全部考卷)" + random;

            //上传压缩包到Oss服务器
            resultURl = bosService.putObject(multipartFile, objectName);

            IOUtils.closeQuietly(input);
            zipFile.delete();
            for (File t : srcFiles) {
                deleteFile(t.getAbsolutePath());
//                boolean mark= t.delete();
            }
        } catch (IOException e) {
            log.error("上传压缩包文件失败！", e.getMessage());
        }


        //返回考卷url集合
        return resultURl;
    }


    public static boolean deleteFile(String path) {
        boolean result = false;
        File file = new File(path);
        if (file.isFile() && file.exists()) {
            int tryCount = 0;
            while (!result && tryCount++ < 10) {
                System.gc();
                result = file.delete();
            }
        }

        return result;
    }

    /**
     * 导出单个学员练习
     *
     * @param studentExerciseId 学生练习id
     * @return
     */
    @Override
    public String exportPersonExercise(Integer studentExerciseId) {
        String resultURl = "";
        //根据学员考试id获取学员考试试卷
        StudentExercisePaperVo result = studentExerciseQuestionService.fetchQuestionsByStudentExerciseIdAnswer(studentExerciseId);

        StringBuffer htmlStr = new StringBuffer();
        htmlStr.append("  <meta charset=\"UTF-8\" /> \n" +
                "  <title>Title</title> \n" +
                "  <style>    * {      margin: 0;      padding: 0;      font-size: 16px;      color: #323232;      font-weight: bold;    }    html,    body {      /*height: 100%;*/    }    .contianer {      width: 500px;      padding: 15px 0 0 15px;      box-sizing: border-box;    }    .flex {      display: flex;    }    .layout_column {      display: flex;      flex-direction: column;    }    .layout_bottom {      display: flex;      align-items: flex-end;    }    .layout_center {      display: flex;      align-items: center;    }    h3 {      text-align: center;    }    .option-box {      padding: 10px 0 0 20px;      box-sizing: border-box;    }    .underline {      width: 80px;      border-bottom: 1px #323232 solid;    }  </style>\n" +
                " </head>\n" +
                "\n" +
                "<body>" +
                "\n");

        htmlStr.append("  <div class=\"contianer\">\n" +
                "    <h3>" + result.getTitle() + "</h3>\n" +
                "    </div>\n"
        );

        int count = 0;


        for (StudentExerciseQuestionVo studentExamQuestionVo : result.getQuestions()) {
            count++;
            //单选题、多选题
            if (studentExamQuestionVo.getQuestionType().equals(QuestionTypeEnum.SINGLE.getValue()) || studentExamQuestionVo.getQuestionType().equals(QuestionTypeEnum.MULTIPLE.getValue())) {
                //单选题、多选题
                if (studentExamQuestionVo.getQuestionType().equals(QuestionTypeEnum.SINGLE.getValue())) {
                    htmlStr.append("<div class=\"paddingTop\"><span><p>" + count + ".(单选题 " + studentExamQuestionVo.getScore() + "分)" + "</p>" + studentExamQuestionVo.getTitle() + "</span></div>");
                } else {
                    htmlStr.append("<div class=\"paddingTop\"><span><p>" + count + ".(多选题 " + studentExamQuestionVo.getScore() + "分)" + "</p>" + studentExamQuestionVo.getTitle() + "</span></div>");
                }
                List<Option> optionList = optionMapper.selectByQuestionId(studentExamQuestionVo.getQuestionId());
                char emumOption = 'A';
                for (Option option : optionList) {
                    htmlStr.append("<div class=\"itemOption\"><span>" + emumOption + "." + option.getContent() + "</span></span></div>");
                    emumOption = (char) (emumOption + 1);

                }
                if (studentExamQuestionVo.getAnswer() == null) {
                    htmlStr.append("<div class=\"paddingTop\">" + "考生答案：" + "未答题" + "</div>");
                } else {
                    String ans = "";
                    List<Integer> submitAnswers = JSON.parseArray(studentExamQuestionVo.getAnswer(), Integer.class);

                    for (int i = 0; i < submitAnswers.size(); i++) {
                        emumOption = 'A';
                        for (Option option : optionList) {
                            if (option.getId().equals(submitAnswers.get(i))) {
                                ans += emumOption;
                                break;
                            }
                            emumOption = (char) (emumOption + 1);
                        }
                    }
                    htmlStr.append("<div class=\"paddingTop\"><p>" + "考生答案：" + ans + "</p><Br><br></div>");
                }

                String ansb = "";
                emumOption = 'A';
                for (Option option : optionList) {
                    if (option.getIfAnswer()) {
                        ansb += emumOption;
                    }
                    emumOption = (char) (emumOption + 1);
                }

                htmlStr.append("<div class=\"paddingTop\"><p>" + "标准答案：" + ansb + "</p></div>");
            }
            //判断题
            else if (studentExamQuestionVo.getQuestionType().equals(QuestionTypeEnum.JUDGE.getValue())) {
                Question qe = questionMapper.selectByPrimaryKey(studentExamQuestionVo.getQuestionId());
                htmlStr.append("<div class=\"itemOption\"><span><p>" + count + ".(判断题 " + studentExamQuestionVo.getScore() + "分)" + "</p>" + studentExamQuestionVo.getTitle() +
                        "<p>对</p>\n" +
                        "<p>错</p>\n" +
                        "\n" +
                        "\n" +
                        "</span></div>");

                List<Integer> submitAnswers = JSON.parseArray(studentExamQuestionVo.getAnswer(), Integer.class);
                if (submitAnswers == null || submitAnswers.size() == 0) {
                    htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "考生答案：" + "未选" + "</p>\n" + "</span></span></div>");
                } else if (submitAnswers.get(0) == 1) {
                    htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "考生答案：" + "对" + "</p>\n" + "</span></span></div>");

                } else {
                    htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "考生答案：" + "错" + "</p>\n" + "</span></span></div>");

                }
                if (qe.getJudgmentAnswer() == true) {
                    htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "标准答案：" + "对" + "</p>\n" + "</span></span></div>");

                } else {
                    htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "标准答案：" + "错" + "</p>\n" + "</span></span></div>");

                }
                htmlStr.append("<br />");
            }

        }

        htmlStr.append("</body>");
        try {
            String html = new String(htmlStr);

            String context = HtmlText.WORD_HEAD + ImageProcessUtil.processImage(html) + HtmlText.WORD_FOOT;
            byte[] b = context.getBytes(StandardCharsets.UTF_8);
            //将字节数组包装到流中
            InputStream inputStream = new ByteArrayInputStream(b);

            long l = System.currentTimeMillis();
            OutputStream outputStream1 = Files.newOutputStream(Paths.get(ww));
            Html2Word poiConvert = new ConvertByPoi(inputStream, outputStream1);
            poiConvert.convert();
            log.info("poi方式导出用时:{}ms", System.currentTimeMillis() - l);

            File file = new File(ww);
            //file转MultipartFile
            FileInputStream input = new FileInputStream(file);
            MultipartFile multipartFile = new MockMultipartFile("file", file.getName(), "text/plain", IOUtils.toByteArray(input));
            String random = UUID.randomUUID().toString().replace("-", "");

            String objectName = result.getTitle() + random;
            resultURl = bosService.putObject(multipartFile, objectName);

            IOUtils.closeQuietly(inputStream);
            IOUtils.closeQuietly(outputStream1);
            IOUtils.closeQuietly(input);
            //删除本地的试卷
            boolean mark = file.delete();
        } catch (IOException e) {
            e.printStackTrace();
        }


        //返回考卷url集合
        return resultURl;
    }


    /**
     * 导出单个学员考卷
     *
     * @param studentExamId 学生考试id
     * @return
     */
    @Override
    public String exportPersonExam(Integer studentExamId) {
        String resultURl = "";
        //根据学员考试id获取学员考试试卷
        StudentExamPaperVo result = studentExamQuestionService.fetchQuestionsByStudentExamId(studentExamId);
        StudentExamVo studentExamVo = studentExamMapper.selectById(studentExamId);
        StringBuffer htmlStr = new StringBuffer();
        htmlStr.append("  <meta charset=\"UTF-8\" /> \n" +
                "  <title>Title</title> \n" +
                "  <style>    * {      margin: 0;      padding: 0;      font-size: 16px;      color: #323232;      font-weight: bold;    }    html,    body {      /*height: 100%;*/    }    .contianer {      width: 500px;      padding: 15px 0 0 15px;      box-sizing: border-box;    }    .flex {      display: flex;    }    .layout_column {      display: flex;      flex-direction: column;    }    .layout_bottom {      display: flex;      align-items: flex-end;    }    .layout_center {      display: flex;      align-items: center;    }    h3 {      text-align: center;    }    .option-box {      padding: 10px 0 0 20px;      box-sizing: border-box;    }    .underline {      width: 80px;      border-bottom: 1px #323232 solid;    }  </style>\n" +
                " </head>\n" +
                "\n" +
                "<body>" +
                "\n");

        htmlStr.append("  <div class=\"contianer\">\n" +
                "    <h3>" + result.getTitle() + "</h3>\n" +

                "    <div class=\"layout_bottom\">\n" +
                "      <span>姓名:</span>\n" + studentExamVo.getStudentName() +
                "      <div class=\"underline\"></div>\n" +
                "    </div>\n" +

                "    <div class=\"flex\">\n" +
                "      <span>注意事项:</span>\n" +
                "      <div class=\"layout_column\">\n" +
                "        <span>1.答题前填写好自己的姓名等信息</span>\n" +
                "<pre>\n" +
                "\n" +
                "</pre>" +

                "        <span>2.请将答案正确填写在答题卡上</span>\n" +
                "      </div>\n" +
                "    </div>\n" +
                "    </div>\n"
        );

        int count = 0;
        for (StudentExamAreaVo studentExamAreaVo : result.getAreas()) {

            for (StudentExamQuestionVo studentExamQuestionVo : studentExamAreaVo.getQuestions()) {
                count++;
                //单选题、多选题
                if (studentExamQuestionVo.getQuestionType().equals(QuestionTypeEnum.SINGLE.getValue()) || studentExamQuestionVo.getQuestionType().equals(QuestionTypeEnum.MULTIPLE.getValue())) {
                    //单选题、多选题
                    if (studentExamQuestionVo.getQuestionType().equals(QuestionTypeEnum.SINGLE.getValue())) {
                        htmlStr.append("<div class=\"paddingTop\"><span><p>" + count + ".(单选题 " + studentExamQuestionVo.getScore() + "分)" + "</p>" + studentExamQuestionVo.getTitle() + "</span></div>");
                    } else {
                        htmlStr.append("<div class=\"paddingTop\"><span><p>" + count + ".(多选题 " + studentExamQuestionVo.getScore() + "分)" + "</p>" + studentExamQuestionVo.getTitle() + "</span></div>");
                    }
                    List<Option> optionList = optionMapper.selectByQuestionId(studentExamQuestionVo.getQuestionId());
                    char emumOption = 'A';
                    for (Option option : optionList) {
                        htmlStr.append("<div class=\"itemOption\"><span>" + emumOption + "." + option.getContent() + "</span></span></div>");
                        emumOption = (char) (emumOption + 1);

                    }
                    if (studentExamQuestionVo.getAnswer() == null) {
                        htmlStr.append("<div class=\"paddingTop\">" + "考生答案：" + "未答题" + "</div>");
                    } else {
                        String ans = "";
                        List<Integer> submitAnswers = JSON.parseArray(studentExamQuestionVo.getAnswer(), Integer.class);

                        for (int i = 0; i < submitAnswers.size(); i++) {
                            emumOption = 'A';
                            for (Option option : optionList) {
                                if (option.getId().equals(submitAnswers.get(i))) {
                                    ans += emumOption;
                                    break;
                                }
                                emumOption = (char) (emumOption + 1);
                            }
                        }
                        htmlStr.append("<div class=\"paddingTop\"><p>" + "考生答案：" + ans + "</p><Br><br></div>");
                    }

                    String ansb = "";
                    emumOption = 'A';
                    for (Option option : optionList) {
                        if (option.getIfAnswer()) {
                            ansb += emumOption;
                        }
                        emumOption = (char) (emumOption + 1);
                    }

                    htmlStr.append("<div class=\"paddingTop\"><p>" + "标准答案：" + ansb + "</p></div>");
                }
                //判断题
                else if (studentExamQuestionVo.getQuestionType().equals(QuestionTypeEnum.JUDGE.getValue())) {

                    htmlStr.append("<div class=\"itemOption\"><span><p>" + count + ".(判断题 " + studentExamQuestionVo.getScore() + "分)" + "</p>" + studentExamQuestionVo.getTitle() +
                            "<p>对</p>\n" +
                            "<p>错</p>\n" +
                            "\n" +
                            "\n" +
                            "</span></div>");

                    List<Integer> submitAnswers = JSON.parseArray(studentExamQuestionVo.getAnswer(), Integer.class);
                    if (submitAnswers == null || submitAnswers.size() == 0) {
                        htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "考生答案：" + "未选" + "</p>\n" + "</span></span></div>");
                    } else if (submitAnswers.get(0) == 1) {
                        htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "考生答案：" + "对" + "</p>\n" + "</span></span></div>");

                    } else {
                        htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "考生答案：" + "错" + "</p>\n" + "</span></span></div>");

                    }
                    if (studentExamQuestionVo.getJudgmentAnswer() == true) {
                        htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "标准答案：" + "对" + "</p>\n" + "</span></span></div>");

                    } else {
                        htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "标准答案：" + "错" + "</p>\n" + "</span></span></div>");

                    }
                    htmlStr.append("<br />");
                }
                //填空题
                else if (studentExamQuestionVo.getQuestionType().equals(QuestionTypeEnum.GAP.getValue())) {
                    htmlStr.append("<div class=\"itemOption\"><span><p>" + count + ".(填空题 " + studentExamQuestionVo.getScore() + "分)" + "</p>" + studentExamQuestionVo.getTitle() + "</span></div>");
                    if (studentExamQuestionVo.getSubjectiveAnswer() == null) {
                        htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "考生答案：未答" + "</p>\n" + "</span></span></div>");

                    } else {
                        htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "考生答案：" + studentExamQuestionVo.getSubjectiveAnswer() + "</p>\n" + "</span></span></div>");
                    }

                    htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "标准答案：" + studentExamQuestionVo.getQuestionAnswer() + "</p>\n" + "</span></span></div>");
                    htmlStr.append("<br />");
                }
                //问答题
                else if (studentExamQuestionVo.getQuestionType().equals(QuestionTypeEnum.ESSAY.getValue())) {
                    htmlStr.append("<div class=\"itemOption\"><span>" + count + ".(问答题 " + studentExamQuestionVo.getScore() + "分)" + studentExamQuestionVo.getTitle() + "</span></div>");
                    if (studentExamQuestionVo.getSubjectiveAnswer() == null) {
                        htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "考生答案：未答" + "</p>\n" + "</span></span></div>");

                    } else {
                        htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "考生答案：" + studentExamQuestionVo.getSubjectiveAnswer() + "</p>\n" + "</span></span></div>");
                    }
                    htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "标准答案：" + studentExamQuestionVo.getQuestionAnswer() + "</p>\n" + "</span></span></div>");
                    htmlStr.append("<br />");
                }
                //材料题
                else if (studentExamQuestionVo.getQuestionType().equals(QuestionTypeEnum.MATERIALS.getValue())) {

                    //材料题题目内容
                    htmlStr.append("<div class=\"paddingTop\"><span><p>" + count + ".(材料题 " + studentExamQuestionVo.getScore() + "分)" + "</p>" + studentExamQuestionVo.getTitle() + "</span></div>");

                    //材料题子题目（判断、单选、多选、问答、填空）
                    //  List<Question> list = questionMapper.selectByParams(null, null, null, null, studentExamQuestionVo.getMaterialQuestionId());

                    List<StudentExamQuestionVo> list = studentExamQuestionVo.getStudentExamQuestionVo();
                    if (list != null && list.size() > 0) {
                        int p = 0;
                        for (StudentExamQuestionVo materialQuestion : list) {
                            p++;
                            //单选题、多选题
                            if (materialQuestion.getQuestionType().equals(QuestionTypeEnum.SINGLE.getValue()) || materialQuestion.getQuestionType().equals(QuestionTypeEnum.MULTIPLE.getValue())) {
                                //题目内容
                                if (materialQuestion.getQuestionType().equals(QuestionTypeEnum.SINGLE.getValue())) {
                                    htmlStr.append("<div class=\"paddingTop\"><span><p>" + p + ".(单选题 " + materialQuestion.getScore() + "分)" + "</p>" + materialQuestion.getTitle() + "</span></div>");
                                } else {
                                    htmlStr.append("<div class=\"paddingTop\"><span><p>" + p + ".(多选题 " + materialQuestion.getScore() + "分)" + "</p>" + materialQuestion.getTitle() + "</span></div>");
                                }

                                List<Option> optionList = optionMapper.selectByQuestionId(materialQuestion.getQuestionId());

                                char emumOption = 'A';
                                for (Option option : optionList) {
                                    htmlStr.append("<div class=\"itemOption\"><span>" + emumOption + "." + option.getContent() + "</span></span></div>");
                                    emumOption = (char) (emumOption + 1);

                                }
                                if (materialQuestion.getAnswer() == null) {
                                    htmlStr.append("<div class=\"paddingTop\"><p>" + "考生答案：" + "未答题" + "</p></div>");
                                } else {
                                    String ans = "";
                                    List<Integer> submitAnswers = JSON.parseArray(materialQuestion.getAnswer(), Integer.class);

                                    for (int i = 0; i < submitAnswers.size(); i++) {
                                        emumOption = 'A';
                                        for (Option option : optionList) {
                                            if (option.getId().equals(submitAnswers.get(i))) {
                                                ans += emumOption;
                                                break;
                                            }
                                            emumOption = (char) (emumOption + 1);
                                        }
                                    }
                                    htmlStr.append("<div class=\"paddingTop\"><p>" + "考生答案：" + ans + "</p></div>");
                                }
                                String ansb = "";
                                emumOption = 'A';
                                for (Option option : optionList) {
                                    if (option.getIfAnswer()) {
                                        ansb += emumOption;
                                    }
                                    emumOption = (char) (emumOption + 1);
                                }
                                htmlStr.append("<div class=\"paddingTop\"><p>" + "标准答案：" + ansb + "</p></div>");
                                htmlStr.append("<br />");
                            }

                            //判断题
                            else if (materialQuestion.getQuestionType().equals(QuestionTypeEnum.JUDGE.getValue())) {

                                htmlStr.append("<div class=\"itemOption\"><span><p>" + p + ".(判断题 " + materialQuestion.getScore() + "分)" + "</p>" + materialQuestion.getTitle() +
                                        "<p>A.对</p>\n" +
                                        "<p>B.错</p>\n" +
                                        "\n" +
                                        "\n" +
                                        "</span></div>");

                                List<Integer> submitAnswers = JSON.parseArray(materialQuestion.getAnswer(), Integer.class);
                                if (submitAnswers == null || submitAnswers.size() == 0) {
                                    htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "考生答案：" + "未选" + "</p>\n" + "</span></span></div>");
                                } else if (submitAnswers.get(0) == 1) {
                                    htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "考生答案：" + "对" + "</p>\n" + "</span></span></div>");

                                } else {
                                    htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "考生答案：" + "错" + "</p>\n" + "</span></span></div>");

                                }
                                if (materialQuestion.getJudgmentAnswer() == true) {
                                    htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "标准答案：" + "对" + "</p>\n" + "</span></span></div>");

                                } else {
                                    htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "标准答案：" + "错" + "</p>\n" + "</span></span></div>");

                                }
                                htmlStr.append("<br />");
                            }
                            //填空题
                            else if (materialQuestion.getQuestionType().equals(QuestionTypeEnum.GAP.getValue())) {
                                htmlStr.append("<div class=\"itemOption\"><span><p>" + p + ".(填空题 " + materialQuestion.getScore() + "分)" + "</p>" + materialQuestion.getTitle() + "</span></div>");
                                if (materialQuestion.getSubjectiveAnswer() == null) {
                                    htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "考生答案：未答 " + "</p>\n" + "</span></span></div>");

                                } else {
                                    htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "考生答案：" + materialQuestion.getSubjectiveAnswer() + "</p>\n" + "</span></span></div>");
                                }
                                htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "标准答案：" + materialQuestion.getQuestionAnswer() + "</p>\n" + "</span></span></div>");
                                htmlStr.append("<br />");
                            }
                            //问答题
                            else if (materialQuestion.getQuestionType().equals(QuestionTypeEnum.ESSAY.getValue())) {
                                htmlStr.append("<div class=\"itemOption\"><span><p>" + p + ".(问答题 " + materialQuestion.getScore() + "分)" + "</p>" + materialQuestion.getTitle() + "</span></div>");

                                if (materialQuestion.getSubjectiveAnswer() == null) {
                                    htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "考生答案：未答" + "</p>\n" + "</span></span></div>");

                                } else {
                                    htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "考生答案：" + materialQuestion.getSubjectiveAnswer() + "</p>\n" + "</span></span></div>");
                                }

                                htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "标准答案：" + materialQuestion.getQuestionAnswer() + "</p>\n" + "</span></span></div>");
                                htmlStr.append("<br />");
                            }
                        }

                    }

                }
            }
        }
        htmlStr.append("</body>");
        try {
            String html = new String(htmlStr);

            String context = HtmlText.WORD_HEAD + ImageProcessUtil.processImage(html) + HtmlText.WORD_FOOT;
            byte[] b = context.getBytes(StandardCharsets.UTF_8);
            //将字节数组包装到流中
            InputStream inputStream = new ByteArrayInputStream(b);

            long l = System.currentTimeMillis();
            OutputStream outputStream1 = Files.newOutputStream(Paths.get(ww));
            Html2Word poiConvert = new ConvertByPoi(inputStream, outputStream1);
            poiConvert.convert();
            log.info("poi方式导出用时:{}ms", System.currentTimeMillis() - l);

            File file = new File(ww);
            //file转MultipartFile
            FileInputStream input = new FileInputStream(file);
            MultipartFile multipartFile = new MockMultipartFile("file", file.getName(), "text/plain", IOUtils.toByteArray(input));
            String random = UUID.randomUUID().toString().replace("-", "");

            String objectName = result.getTitle() + "(" + studentExamVo.getStudentName() + ")" + random;
            resultURl = bosService.putObject(multipartFile, objectName);

            IOUtils.closeQuietly(inputStream);
            IOUtils.closeQuietly(outputStream1);
            IOUtils.closeQuietly(input);
            //删除本地的试卷
            boolean mark = file.delete();
            System.out.println(mark);


        } catch (IOException e) {
            e.printStackTrace();
        }


        //返回考卷url集合
        return resultURl;
    }

    @Override
    public String exportPersonSubjectiveExam(List<Integer> studentExamIdList) {
        String resultURl = "";
        List<StringBuffer> htmlStrList = new ArrayList<>();

        //考卷名称集合（命名规则：排序值+考试名称+考生姓名）
        List<String> studentNameList = new ArrayList<>();
        if (studentExamIdList != null && studentExamIdList.size() > 0) {
            for (int i = 0; i < studentExamIdList.size(); i++) {
                StudentExamVo studentExamVo = studentExamMapper.selectById(studentExamIdList.get(i));

                //根据学员考试id获取学员考试试卷
                StudentExamPaperVo result = studentExamQuestionService.fetchQuestionsByStudentExamId(studentExamIdList.get(i));
                StringBuffer htmlStr = new StringBuffer();
                htmlStr.append("  <meta charset=\"UTF-8\" /> \n" +
                        "  <title>Title</title> \n" +
                        "  <style>    * {      margin: 0;      padding: 0;      font-size: 16px;      color: #323232;      font-weight: bold;    }    html,    body {      /*height: 100%;*/    }    .contianer {      width: 500px;      padding: 15px 0 0 15px;      box-sizing: border-box;    }    .flex {      display: flex;    }    .layout_column {      display: flex;      flex-direction: column;    }    .layout_bottom {      display: flex;      align-items: flex-end;    }    .layout_center {      display: flex;      align-items: center;    }    h3 {      text-align: center;    }    .option-box {      padding: 10px 0 0 20px;      box-sizing: border-box;    }    .underline {      width: 80px;      border-bottom: 1px #323232 solid;    }  </style>\n" +
                        " </head>\n" +
                        "\n" +
                        "<body>" +
                        "\n");

                htmlStr.append("  <div class=\"contianer\">\n" +
                        "    <h3>" + result.getTitle() + "</h3>\n" +

                        "    <div class=\"layout_bottom\">\n" +
                        "      <span>姓名:</span>\n" + studentExamVo.getStudentName() +
                        "    <br/>\n" +
                        "      <span>考试开始时间:</span>\n" + studentExamVo.getStartDate() +
                        "      <div class=\"underline\"></div>\n" +
                        "    </div>\n" +
                        "    </div>\n" +
                        "    <br/>\n"
                );

                int count = 0;
                for (StudentExamAreaVo studentExamAreaVo : result.getAreas()) {

                    for (StudentExamQuestionVo studentExamQuestionVo : studentExamAreaVo.getQuestions()) {

                        //问答题
                        if (studentExamQuestionVo.getQuestionType().equals(QuestionTypeEnum.ESSAY.getValue())) {
                            count++;
                            htmlStr.append("<div class=\"itemOption\"><span>" + count + ".(案例题 " + studentExamQuestionVo.getScore() + "分)" + studentExamQuestionVo.getTitle() + "</span></div>");
                            if (studentExamQuestionVo.getSubjectiveAnswer() == null) {
                                htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "考生答案：未答" + "</p>\n" + "</span></span></div>");

                            } else {
                                htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "考生答案：" + studentExamQuestionVo.getSubjectiveAnswer() + "</p>\n" + "</span></span></div>");
                            }
                            htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "标准答案：" + studentExamQuestionVo.getQuestionAnswer() + "</p>\n" + "</span></span></div>");
                            htmlStr.append("<div class=\"itemOption\"><span>" + "<p>" + "得分：（   ）" + "</p>\n" + "</span></span></div>");
                            htmlStr.append("<br />");

                        }

                    }
                }
                htmlStr.append("</body>");
                htmlStrList.add(i, htmlStr);
                String name = "(" + i + ")" + result.getTitle() + studentExamVo.getStudentName();
                studentNameList.add(i, name);
            }
        }
        if (studentExamIdList.size() == 1) {

            try {
                String html = new String(htmlStrList.get(0));
                String context = HtmlText.WORD_HEAD + ImageProcessUtil.processImage(html) + HtmlText.WORD_FOOT;
                byte[] b = context.getBytes(StandardCharsets.UTF_8);
                //将字节数组包装到流中
                InputStream inputStream = new ByteArrayInputStream(b);

                long l = System.currentTimeMillis();
                String newFileName = word + studentNameList.get(0) + ".doc";

                File file = new File(newFileName);
                try {
                    // 创建新的文件，前提是必须文件夹已经存在，即D:/File已经存在，文件夹名字不区分大小写：
                    file.createNewFile();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                OutputStream outputStream1 = Files.newOutputStream(Paths.get(newFileName));
                Html2Word poiConvert = new ConvertByPoi(inputStream, outputStream1);
                poiConvert.convert();
                log.info("poi方式导出用时:{}ms", System.currentTimeMillis() - l);

                //file转MultipartFile
                FileInputStream input = new FileInputStream(file);
                MultipartFile multipartFile = new MockMultipartFile("file", file.getName(), "text/plain", IOUtils.toByteArray(input));
                String random = UUID.randomUUID().toString().replace("-", "");

                String objectName = studentNameList.get(0) + random + ".doc";
                resultURl = bosService.putObject(multipartFile, objectName);
                IOUtils.closeQuietly(inputStream);
                IOUtils.closeQuietly(outputStream1);
                IOUtils.closeQuietly(input);
                //删除本地的试卷
                file.delete();
            } catch (IOException e) {
                e.printStackTrace();
            }

        } else {
            File[] srcFiles = new File[studentExamIdList.size()];
            int count = 0;
            for (StringBuffer htmlStr : htmlStrList) {

                try {
                    String html = new String(htmlStr);

                    String context = HtmlText.WORD_HEAD + ImageProcessUtil.processImage(html) + HtmlText.WORD_FOOT;
                    byte[] b = context.getBytes(StandardCharsets.UTF_8);
                    //将字节数组包装到流中
                    InputStream inputStream = new ByteArrayInputStream(b);

                    long l = System.currentTimeMillis();

                    String newFileName = word + studentNameList.get(count) + ".doc";

                    File file = new File(newFileName);
                    try {
                        // 创建新的文件，前提是必须文件夹已经存在，即D:/File已经存在，文件夹名字不区分大小写：
                        file.createNewFile();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    OutputStream outputStream1 = Files.newOutputStream(Paths.get(newFileName));
                    Html2Word poiConvert = new ConvertByPoi(inputStream, outputStream1);
                    poiConvert.convert();
                    log.info("poi方式导出用时:{}ms", System.currentTimeMillis() - l);
                    IOUtils.closeQuietly(inputStream);
                    IOUtils.closeQuietly(outputStream1);

                    srcFiles[count++] = file;
                    //删除本地的试卷
//                file.delete();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }

            try {
                File zipFile = new File(word + "ZipFile.zip");
                // 调用压缩方法
                zipFiles(srcFiles, zipFile);
                //file转MultipartFile
                FileInputStream input = new FileInputStream(zipFile);
                MultipartFile multipartFile = new MockMultipartFile("file", zipFile.getName(), "text/plain", IOUtils.toByteArray(input));
                String random = UUID.randomUUID().toString().replace("-", "");

                String objectName = random + "(主观题部分)";

                //上传压缩包到Oss服务器
                resultURl = bosService.putObject(multipartFile, objectName);

                IOUtils.closeQuietly(input);
                zipFile.delete();
                for (File t : srcFiles) {
                    deleteFile(t.getAbsolutePath());
                }
            } catch (IOException e) {
                log.error("上传压缩包文件失败！", e.getMessage());
            }
        }
        //返回考卷url集合
        return resultURl;
    }


    // 删除指定文件夹下所有文件
// param path 文件夹完整绝对路径
    public static boolean delAllFile(String path) {
        boolean flag = false;
        File file = new File(path);
        if (!file.exists()) {
            return flag;
        }
        if (!file.isDirectory()) {
            return flag;
        }
        String[] tempList = file.list();
        File temp = null;
        for (int i = 0; i < tempList.length; i++) {
            if (path.endsWith(File.separator)) {
                temp = new File(path + tempList[i]);
            } else {
                temp = new File(path + File.separator + tempList[i]);
            }
            if (temp.isFile()) {
                temp.delete();
            }
            if (temp.isDirectory()) {
                delAllFile(path + "/" + tempList[i]);// 先删除文件夹里面的文件
                delFolder(path + "/" + tempList[i]);// 再删除空文件夹
                flag = true;
            }
        }
        return flag;
    }
// 删除文件夹
// param folderPath 文件夹完整绝对路径

    public static void delFolder(String folderPath) {
        try {
            delAllFile(folderPath); // 删除完里面所有内容
            String filePath = folderPath;
            filePath = filePath.toString();
            java.io.File myFilePath = new java.io.File(filePath);
            myFilePath.delete(); // 删除空文件夹
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 下载图片
     *
     * @param urlString 路径
     * @param filename  保存的文件名
     * @param savePath  保存路径
     */
    public static void download(String urlString, String filename, String savePath) {
        InputStream is = null;
        OutputStream os = null;
        try {
            // 构造URL
            URL url = new URL(urlString);
            // 打开连接
            URLConnection con = url.openConnection();
            //设置请求超时为5s
            con.setConnectTimeout(5 * 1000);
            // 输入流
            is = con.getInputStream();

            // 1K的数据缓冲
            byte[] bs = new byte[1024];
            // 读取到的数据长度
            int len;
            // 输出的文件流
            File sf = new File(savePath);
            if (!sf.exists()) {
                sf.mkdirs();
            }
            os = new FileOutputStream(sf.getPath() + "\\" + filename);
            // 开始读取
            while ((len = is.read(bs)) != -1) {
                os.write(bs, 0, len);
            }
            // 完毕，关闭所有链接
            os.close();
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * @describe 压缩多个文件
     * @author zfc
     * @date 2018年1月11日 下午8:34:00
     */

//        public static void main(String[] args) {
//            File[] srcFiles = { new File("E:\\母亲.mp4"), new File("E:\\飞机.pdf"), new File("E:\\家里密码.txt") };
//            File zipFile = new File("E:\\ZipFile.zip");
//            // 调用压缩方法
//            zipFiles(srcFiles, zipFile);
//        }
    public static void zipFiles(File[] srcFiles, File zipFile) {
        // 判断压缩后的文件存在不，不存在则创建
        if (!zipFile.exists()) {
            try {
                zipFile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        // 创建 FileOutputStream 对象
        FileOutputStream fileOutputStream = null;
        // 创建 ZipOutputStream
        ZipOutputStream zipOutputStream = null;
        // 创建 FileInputStream 对象
        FileInputStream fileInputStream = null;

        try {
            // 实例化 FileOutputStream 对象
            fileOutputStream = new FileOutputStream(zipFile);
            // 实例化 ZipOutputStream 对象
            zipOutputStream = new ZipOutputStream(fileOutputStream);
            // 创建 ZipEntry 对象
            ZipEntry zipEntry = null;
            // 遍历源文件数组
            for (int i = 0; i < srcFiles.length; i++) {
                // 将源文件数组中的当前文件读入 FileInputStream 流中
                fileInputStream = new FileInputStream(srcFiles[i]);
                // 实例化 ZipEntry 对象，源文件数组中的当前文件
                zipEntry = new ZipEntry(srcFiles[i].getName());
                zipOutputStream.putNextEntry(zipEntry);
                // 该变量记录每次真正读的字节个数
                int len;
                // 定义每次读取的字节数组
                byte[] buffer = new byte[1024];
                while ((len = fileInputStream.read(buffer)) > 0) {
                    zipOutputStream.write(buffer, 0, len);
                }
            }
            zipOutputStream.closeEntry();
            zipOutputStream.close();
            fileInputStream.close();
            fileOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * 获取资源文件的文件流
     *
     * @return
     */
    public static InputStream getResourceInputStream(String filePath) {
        InputStream in = FileUtil.class.getResourceAsStream(filePath);
        if (in != null) {
            return in;
        }
        return null;
    }


}


